package org.aplikator.client.widgets;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

import org.aplikator.client.Aplikator.AplikatorResources;
import org.aplikator.client.descriptor.PropertyDTO;

import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.TextBox;

public class TextFieldWidget<T extends Serializable> extends DataFieldBase<T> implements DataField<T> {
    private TextBox box = new TextBox();

    public TextFieldWidget(String caption, PropertyDTO<T> property, boolean labelAbove, String width) {
        super(caption, property, false, labelAbove);
        add(box);
        box.addStyleName(PaneWidgetResources.INSTANCE.css().formData());
        box.addValueChangeHandler(new ValueChangeHandler<String>() {
            public void onValueChange(ValueChangeEvent<String> event) {
                setDirty(true);
            }
        });
        if (property.getRefferedThrough() != null) {
            this.setEnabled(false);
        }
        if (width != null) {
            box.setWidth(width);
        } else {
            box.setWidth("" + Math.max(10, Math.floor(property.getSize() / 10) ) + "em");
        }
    }

    public void setValue(T value) {
        box.setValue(value != null? value.toString():null);
    }

    @SuppressWarnings({ "unchecked", "deprecation" })
    public T getValue() {
        String strVal =  box.getValue();
        if (strVal == null) return null;
        String type = getProperty().getType();
        if ("java.lang.String".equals(type)){
            return (T) strVal;
        } else if ("java.lang.Integer".equals(type)){
            try{
                return (T) Integer.decode(strVal);
            }catch(NumberFormatException ex){
                return null; //TODO notify user
            }
        } else if ("java.math.BigDecimal".equals(type)){
            try{
                return (T) new BigDecimal(strVal);
            } catch(NumberFormatException ex){
                return null; //TODO notify user
            }
        } else if ("java.util.Date".equals(type)){
            try{
                return (T) new Date(strVal);
            } catch(IllegalArgumentException ex){
                return null; //TODO notify user
            }
        } else {
            throw new IllegalStateException("TextFieldWidget does not support the data type "+type);
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public HandlerRegistration addValueChangeHandler(ValueChangeHandler handler) {
        return box.addValueChangeHandler(handler);
    }

    public void setEnabled(boolean enabled) {
        box.setEnabled(enabled);
    }

    public void setDirty(boolean dirty) {
        super.setDirty(dirty);
        if (dirty) {
            box.addStyleName(AplikatorResources.INSTANCE.css().dirty());
        } else {
            box.removeStyleName(AplikatorResources.INSTANCE.css().dirty());
        }
    }

}
